package org.dromara.wmscloud.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.wmscloud.bean.InDetailPdfData;
import org.dromara.wmscloud.bean.InOrderPdfData;
import org.dromara.wmscloud.bean.typeEnum.OrderStatusEnum;
import org.dromara.wmscloud.domain.vo.StockInDetailVo;
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.wmscloud.utils.PDFService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.wmscloud.domain.vo.StockInOrderVo;
import org.dromara.wmscloud.domain.bo.StockInOrderBo;
import org.dromara.wmscloud.service.IStockInOrderService;
import org.dromara.common.mybatis.core.page.TableDataInfo;

/**
 * 入库单
 *
 * @author hou
 * @date 2025-04-17
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/wmsCloud/inOrder")
public class StockInOrderController extends BaseController {

    private final IStockInOrderService stockInOrderService;
    private final PDFService pdfService;
    /**
     * 查询入库单列表
     */
    @SaCheckPermission("stock:inOrder:list")
    @GetMapping("/list")
    public TableDataInfo<StockInOrderVo> list(StockInOrderBo bo, PageQuery pageQuery) {
        return stockInOrderService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出入库单列表
     */
    @SaCheckPermission("stock:inOrder:export")
    @Log(title = "入库单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(StockInOrderBo bo, HttpServletResponse response) {
        //TODO 入库单详情导出
        List<StockInOrderVo> list = stockInOrderService.queryList(bo);
        ExcelUtil.exportExcel(list, "入库单", StockInOrderVo.class, response);
    }

    /**
     * 获取入库单详细信息
     *
     * @param orderId 主键
     */
    @SaCheckPermission("stock:inOrder:query")
    @GetMapping("/{orderId}")
    public R<StockInOrderVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long orderId) {
        return R.ok(stockInOrderService.queryById(orderId));
    }

    /**
     * 新增入库单
     */
    @SaCheckPermission("stock:inOrder:add")
    @Log(title = "入库单", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody StockInOrderBo bo) {
        return toAjax(stockInOrderService.insertByBo(bo));
    }

    /**
     * 修改入库单
     */
    @SaCheckPermission("stock:inOrder:edit")
    @Log(title = "入库单", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody StockInOrderBo bo) {
        return toAjax(stockInOrderService.updateByBo(bo));
    }

    /**
     * 删除入库单
     *
     * @param orderIds 主键串
     */
    @SaCheckPermission("stock:inOrder:remove")
    @Log(title = "入库单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{orderIds}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] orderIds) {
        return toAjax(stockInOrderService.deleteWithValidByIds(List.of(orderIds), true));
    }

    /**
     * 打印入库单详情
     *
     *  @param orderId 主键串
     */
    @SaCheckPermission("stock:inOrder:print")
    @Log(title = "入库单详情", businessType = BusinessType.OTHER)
    @GetMapping("printInOrderDetail/{orderId}")
    public void printInOrderDetail(HttpServletResponse response, @PathVariable Long orderId) throws Exception{
        OutputStream out = response.getOutputStream();
        response.setContentType("application/pdf");
        StockInOrderVo stockInOrderVo = stockInOrderService.queryById(orderId);
        if(stockInOrderVo != null){
            //更新入库单状态
            StockInOrderBo stockInOrderBo = new StockInOrderBo();
            stockInOrderBo.setOrderId(orderId);
            stockInOrderBo.setOrderStatus(OrderStatusEnum.PRINTED.getValue());
            stockInOrderService.updateByBo(stockInOrderBo);
            //打印入库单数据
            InOrderPdfData orderPdfData = new InOrderPdfData();
            orderPdfData.setOrderType(stockInOrderVo.getOrderType());
            orderPdfData.setOrderNo(stockInOrderVo.getOrderNo());
            orderPdfData.setCreateBy(stockInOrderVo.getCreateBy());
            orderPdfData.setCreateTime(stockInOrderVo.getCreateTime());

            List<InDetailPdfData> detailPdfDataList = new ArrayList<>();
            InDetailPdfData detailPdfData = null;
            List<StockInDetailVo> detailList  = stockInOrderVo.getDetailList();
            if (CollectionUtils.isNotEmpty(detailList))   {
                for (StockInDetailVo detail : detailList) {
                    detailPdfData = new InDetailPdfData();
                    detailPdfData.setQuantity(detail.getQuantity());
                    detailPdfData.setMatCode(detail.getMatCode());
                    detailPdfData.setMatName(detail.getMatName());
                    detailPdfData.setFigNum(detail.getFigNum());
                    detailPdfData.setUnitName(detail.getUnitCode());
                    detailPdfData.setSupplierName(detail.getSupplierName());
                    detailPdfData.setBatch(detail.getBatch());
                    detailPdfData.setUnitPrice(detail.getUnitPrice());
                    detailPdfDataList.add(detailPdfData);
                }
            }
            InputStream in = new FileInputStream(new File(pdfService.printInOrder(orderPdfData, detailPdfDataList)));
            int len = 0;
            byte[] buffer = new byte[1024];
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }

            in.close();
        }
    }
}
